/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "kh_sle_host.h"
#include "kh_sle_announce.h"
#include "sle_announce_hal.h"
#include "sle_announce_config.h"
#include "sle_hilog.h"
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <cmsis_os2.h>
#include "sle_lite_advance_setting.h"

#ifndef ServiceCallbackNumFlag
#define ServiceCallbackNumFlag
#define serviceCallbackNum  3
#endif  // ServiceCallbackNumFlag
static bool g_isAnnounceServiceInit = false;
static SleAnnounceState g_announceState[SLE_MAX_ANNOUNCE_ID_NUM] = {SLE_ANNOUNCE_ERROR_STATE};

static SleAnnounceCallbacks* g_announceCallbacks[serviceCallbackNum] = {NULL};
static SleAnnounceHalCallbacks* g_AnnounceHalCallback = NULL;
static osMutexId_t g_announceCallbcakMuxHandle = 0;
static osSemaphoreId_t g_sleAnnounceSemHandle = 0;
static uint32_t SleAnnounceTimeOut = 300;
static SleErrorCode g_sleAnnounceAsyncRet = SLE_ERR_UNKNOWN;


void NotifySleAnnounceStateChangeCallback(uint8_t announceId, SleAnnounceState announceState, bool isTerminaled)
{
    SLE_LOGI("NotifySleAnnounceStateChangeCallback in announceId(%d) announceState(%s) isTerminaled(%d)", announceId, SleAnnounceStateStr(announceState), isTerminaled);
    g_announceState[announceId -1] = announceState;
    for(int i = 0; i < serviceCallbackNum; i++) {
        if(g_announceCallbacks[i] != NULL && g_announceCallbacks[i]->OnSleAnnounceStateChangeCb != NULL) {
            g_announceCallbacks[i]->OnSleAnnounceStateChangeCb(announceId, announceState, isTerminaled);
        }
    }
}

void OnSleAnnounceHalStartAnnounceCallback(uint8_t announceId, SleHalErrorCode errCode)
{
    SLE_LOGD("OnSleAnnounceHalStartAnnounceCallback in announceId(%d) errCode(%d)", announceId, errCode);
    g_sleAnnounceAsyncRet = (SleErrorCode)errCode;
    osSemaphoreRelease(g_sleAnnounceSemHandle);
    if(errCode == SLE_HAL_SUCCESS) {
        NotifySleAnnounceStateChangeCallback(announceId, SLE_ANNOUNCE_ENABLED_STATE, false);
    } else {
        g_announceState[announceId -1] = SLE_ANNOUNCE_DISABLED_STATE;
    }
}

void OnSleAnnounceHalStopAnnounceCallback(uint8_t announceId, SleHalErrorCode errCode)
{
    SLE_LOGD("OnSleAnnounceHalStopAnnounceCallback in announceId(%d) errCode(%d)", announceId, errCode);
    g_sleAnnounceAsyncRet = (SleErrorCode)errCode;
    osSemaphoreRelease(g_sleAnnounceSemHandle);
    if(errCode == SLE_HAL_SUCCESS) {
        NotifySleAnnounceStateChangeCallback(announceId, SLE_ANNOUNCE_DISABLED_STATE, false);
    } else {
        g_announceState[announceId -1] = SLE_ANNOUNCE_ENABLED_STATE;
    }
}

void OnSleAnnounceHalTerminalAnnounceCallbcak(uint8_t announceId)
{
    SLE_LOGD("OnSleAnnounceHalTerminalAnnounceCallbcak in announceId(%d)", announceId);
    NotifySleAnnounceStateChangeCallback(announceId, SLE_ANNOUNCE_DISABLED_STATE, true);
}

void OnSleHalRemoveAnnounceCallbcak(uint8_t announceId, SleHalErrorCode errCode)
{
    SLE_LOGD("OnSleHalRemoveAnnounceCallbcak in announceId(%d) errCode(%d)", announceId, errCode);
    //TODO: 增加remove announce的同步接口
    // g_sleAnnounceAsyncRet = (SleErrorCode)errCode;
    // osSemaphoreRelease(g_sleAnnounceSemHandle);
}

SleErrorCode InitSleAnnounceService(void)
{
    SLE_LOGI("InitSleAnnounceService In");
    SLE_ASSERT_AND_RETURN_RET(g_isAnnounceServiceInit == false, SLE_NO_ERROR);
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = InitSleAnnounceHal();
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);

    if (g_announceCallbcakMuxHandle == 0) {
      osMutexAttr_t attr = {
            .name = "sle_announce_mux",
        };
        g_announceCallbcakMuxHandle = osMutexNew(&attr);
    }
    if (g_sleAnnounceSemHandle == 0) {
        g_sleAnnounceSemHandle = osSemaphoreNew(1, 0, NULL);
    }
    if(g_AnnounceHalCallback == NULL) {
        g_AnnounceHalCallback = (SleAnnounceHalCallbacks*)malloc(sizeof(SleAnnounceHalCallbacks));
        SLE_ASSERT_AND_RETURN_RET(g_AnnounceHalCallback != NULL, SLE_ERR_SYSTEM_WRONG);
        g_AnnounceHalCallback->OnAnnounceHalStartAnnounceCb = OnSleAnnounceHalStartAnnounceCallback;
        g_AnnounceHalCallback->OnAnnounceHalStopAnnounceCb = OnSleAnnounceHalStopAnnounceCallback;
        g_AnnounceHalCallback->OnAnnounceHalTerminalAnnounceCb = OnSleAnnounceHalTerminalAnnounceCallbcak;
       g_AnnounceHalCallback-> OnAnnounceHalRemoveAnnounceCb = OnSleHalRemoveAnnounceCallbcak;
    }

    ret = (SleErrorCode) SleAnnounceHalRegisterCallbacks(g_AnnounceHalCallback);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);

    g_sleAnnounceAsyncRet = SLE_ERR_UNKNOWN;
    g_isAnnounceServiceInit = true;
    for(int i = 0; i < SLE_MAX_ANNOUNCE_ID_NUM; i++) {
        g_announceState[i] = SLE_ANNOUNCE_ERROR_STATE;
    }
    return ret;
}

SleErrorCode CheckCanOprateAnnounce(void)
{
    SLE_ASSERT_AND_RETURN_RET(g_isAnnounceServiceInit == true, SLE_ERR_NOT_READY);
    SleDeviceState hostState;
    SleErrorCode ret = GetSleState(&hostState);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    SLE_ASSERT_AND_RETURN_RET(hostState == SLE_HOST_STATE_ENABLED, SLE_ERR_STATUS_WRONG);
    return SLE_NO_ERROR;
}

SleErrorCode DeinitSleAnnounceService(void)
{
    SLE_LOGI("DeinitSleAnnounceService In");
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = CheckCanOprateAnnounce();
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    ret = DeinitSleAnnounceHal();
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);

    osMutexAcquire(g_announceCallbcakMuxHandle, 0);
    if (g_announceCallbcakMuxHandle == 0) {
        SLE_LOGW("g_announceCallbcakMuxHandle is 0");
        return SLE_NO_ERROR;
    }
    osMutexRelease(g_announceCallbcakMuxHandle);

    osMutexDelete(g_announceCallbcakMuxHandle);
    g_announceCallbcakMuxHandle = 0;
    osSemaphoreDelete(g_sleAnnounceSemHandle);
    g_sleAnnounceSemHandle = 0;
    g_sleAnnounceAsyncRet = SLE_ERR_UNKNOWN;
    g_isAnnounceServiceInit = false;
    for(int i = 0; i < SLE_MAX_ANNOUNCE_ID_NUM; i++) {
        g_announceState[i] = SLE_ANNOUNCE_ERROR_STATE;
    }
    return ret;
}

SleErrorCode AddAnnounce(uint8_t *announceId)
{
    SLE_LOGI("AddAnnounce");
    SLE_ASSERT_AND_RETURN_RET(announceId != NULL, SLE_ERR_INVALID_PARAM);
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = CheckCanOprateAnnounce();
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    
    for (uint8_t i = 0; i < SLE_MAX_ANNOUNCE_ID_NUM; i++)
    {
        if(g_announceState[i] == SLE_ANNOUNCE_ERROR_STATE) {
            g_announceState[i] = SLE_ANNOUNCE_DISABLED_STATE;
            *announceId = i + 1;
            return SLE_NO_ERROR;
        }
    }
    return SLE_ERR_OUT_RANGE;
}

SleErrorCode RemoveAnnounce(uint8_t announceId)
{
    SLE_LOGI("RemoveAnnounce announceId(%d)", announceId);
    SLE_ASSERT_AND_RETURN_RET(announceId >= 1 && announceId <= SLE_MAX_ANNOUNCE_ID_NUM, SLE_ERR_INVALID_PARAM);
    SLE_ASSERT_AND_RETURN_RET(g_isAnnounceServiceInit == true, SLE_ERR_NOT_READY);
    SLE_ASSERT_AND_RETURN_RET(g_announceState[announceId -1] != SLE_ANNOUNCE_ERROR_STATE, SLE_NO_ERROR);
    SLE_ASSERT_AND_RETURN_RET(g_announceState[announceId -1] == SLE_ANNOUNCE_DISABLED_STATE, SLE_ERR_STATUS_WRONG);
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = CheckCanOprateAnnounce();
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    g_announceState[announceId -1] = SLE_ANNOUNCE_ERROR_STATE;
    return ret;
}

static SleErrorCode CheckAnnounceParam(const SleAnnounceParam *param)
{
    SLE_ASSERT_AND_RETURN_RET_LOG((param->mode >= SLE_ANNOUNCE_NONCONN_NONSCAN_MODE && param->mode <= SLE_ANNOUNCE_CONNECTABLE_SCANABLE_MODE) ||
        param->mode == SLE_ANNOUNCE_CONNECTABLE_DIRECTED_MODE, SLE_ERR_INVALID_PARAM, "param announce mode error!");
    SLE_ASSERT_AND_RETURN_RET_LOG(param->role >= SLE_ANNOUNCE_T_ROAL_CAN_NEGO && param->role <= SLE_ANNOUNCE_G_ROAL_NO_NEGO,
        SLE_ERR_INVALID_PARAM, "param announce role error!");
    SLE_ASSERT_AND_RETURN_RET_LOG(param->level >= SLE_ANNOUNCE_NONE_LEVEL && param->level <= SLE_ANNOUNCE_SPECIAL_LEVEL,
        SLE_ERR_INVALID_PARAM, "param announce level error!");
    SLE_ASSERT_AND_RETURN_RET_LOG(param->annonceIntervalMin >= 0x000020 && param->annonceIntervalMin <= 0xFFFFFF,
        SLE_ERR_INVALID_PARAM, "param announce interval min error!");
    SLE_ASSERT_AND_RETURN_RET_LOG(param->annonceIntervalMax >= 0x000020 && param->annonceIntervalMax <= 0xFFFFFF,
        SLE_ERR_INVALID_PARAM, "param announce interval max error!");
    SLE_ASSERT_AND_RETURN_RET_LOG(param->annonceIntervalMin <= param->annonceIntervalMax,
        SLE_ERR_INVALID_PARAM, "param announce interval error!");
    SLE_ASSERT_AND_RETURN_RET_LOG(param->channelMap == SLE_ANNOUNCE_76_CHANEL || param->channelMap == SLE_ANNOUNCE_77_CHANEL ||
        param->channelMap == SLE_ANNOUNCE_78_CHANEL || param->channelMap == SLE_ANNOUNCE_DEFAULT_ALL_CHANEL, SLE_ERR_INVALID_PARAM,
            "param announce interval max error!");
    if (param->role != SLE_ANNOUNCE_T_ROAL_NO_NEGO) {
        SLE_ASSERT_AND_RETURN_RET_LOG(param->connectIntervalMin >= 0x000A && param->connectIntervalMin <= 0x3E80,
            SLE_ERR_INVALID_PARAM, "param announce connect interval min error!");
        SLE_ASSERT_AND_RETURN_RET_LOG(param->connectIntervalMax >= 0x000A && param->connectIntervalMax <= 0x3E80,
            SLE_ERR_INVALID_PARAM, "param announce connect interval max error!");
        SLE_ASSERT_AND_RETURN_RET_LOG(param->connectIntervalMin <= param->connectIntervalMax,
            SLE_ERR_INVALID_PARAM, "param announce connect interval error!");
        SLE_ASSERT_AND_RETURN_RET_LOG(param->connectLatency <= 0x01F3,
            SLE_ERR_INVALID_PARAM, "param announce connect latency error!");
        SLE_ASSERT_AND_RETURN_RET_LOG(param->connectTimeout <= 0x0C80,
            SLE_ERR_INVALID_PARAM, "param announce connect timeout error!");
        SLE_ASSERT_AND_RETURN_RET_LOG(param->connectLatency < param->connectTimeout,
            SLE_ERR_INVALID_PARAM, "param announce connect latency than timeout error!");
    }
    return SLE_NO_ERROR;
}

static SleErrorCode CheckAnnounceData(const SleAnnounceData *data)
{
    SLE_ASSERT_AND_RETURN_RET_LOG(data->announceData && data->responceData,
        SLE_ERR_INVALID_PARAM, "param announce data or rspdata ptr not init error!");
    SLE_ASSERT_AND_RETURN_RET_LOG(data->announceLength <= SLE_ANNOUNCE_DATA_ANN_MAX_LENGTH,
        SLE_ERR_INVALID_PARAM, "param announce data length error!");
    SLE_ASSERT_AND_RETURN_RET_LOG(data->responceLength <= SLE_ANNOUNCE_DATA_MAX_RSP_LENGTH,
        SLE_ERR_INVALID_PARAM, "param announce rsp data length error!");
    return SLE_NO_ERROR;
}

SleErrorCode SetAnnounceParam(uint8_t announceId, const SleAnnounceParam *param)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    SleAnnounceParam defaultParam = {
        .handle = 1,
        .mode = DEFAULT_SLE_ADV_MODE,
        .role = DEFAULT_SLE_ADV_ROLE,
        .level = DEFAULT_SLE_ADV_LEVEL,
        .channelMap = DEFAULT_SLE_ADV_CHANNEL_MAP,
        .annonceIntervalMin = DEFAULT_SLE_ADV_INTERVAL_MIN,
        .annonceIntervalMax = DEFAULT_SLE_ADV_INTERVAL_MAX,
        .txPower = DEFAULT_SLE_ADV_TX_POWER,
        .connectIntervalMin = DEFAULT_SLE_ADV_CONN_INTV_MIN,
        .connectIntervalMax = DEFAULT_SLE_ADV_CONN_INTV_MAX,
        .connectLatency = DEFAULT_SLE_ADV_CONN_AX_LATENCY,
        .connectTimeout = DEFAULT_SLE_ADV_CONN_SUPERVISION_TIMEOUT,
    };

    if(param != NULL) {
        ret = CheckAnnounceParam(param);
        SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
        memcpy(&defaultParam, param, sizeof(SleAnnounceParam));
    }
    defaultParam.ownAddr.addrType = SLE_PUBLIC_ADDRESS_TYPE;
    ret = GetHostAddress(&defaultParam.ownAddr);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    ret = SleAnnounceHalSetAnnounceParam(announceId, &defaultParam);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    return SLE_NO_ERROR;
}

SleErrorCode SetAnnounceData(uint8_t announceId, SleAnnounceData *data)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = CheckAnnounceData(data);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    ret = SleAnnounceHalSetAnnounceData(announceId, data);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    return SLE_NO_ERROR;
}

SleErrorCode StartAnnounceAsync(uint8_t announceId, SleAnnounceData *announceData, const SleAnnounceParam *announceParam)
{
    SleErrorCode ret = CheckCanOprateAnnounce();
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    SLE_ASSERT_AND_RETURN_RET(announceId >= 1 && announceId <= SLE_MAX_ANNOUNCE_ID_NUM, SLE_ERR_INVALID_PARAM);
    SLE_ASSERT_AND_RETURN_RET(announceData != NULL, SLE_ERR_INVALID_PARAM);
    SLE_ASSERT_AND_RETURN_RET(g_announceState[announceId -1] != SLE_ANNOUNCE_ENABLED_STATE, SLE_ERR_EBABLE_ANNOUNCE_SUCCESS_WHEN_ANNOUNCE);
    SLE_ASSERT_AND_RETURN_RET(g_announceState[announceId -1] == SLE_ANNOUNCE_DISABLED_STATE, SLE_ERR_STATUS_WRONG);
    ret = SetAnnounceParam(announceId, announceParam);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    ret = SetAnnounceData(announceId, announceData);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    ret = SleAnnounceHalStartAnnounce(announceId);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    g_announceState[announceId -1] = SLE_ANNOUNCE_ENABLING_STATE;
    return ret;
}

SleErrorCode StartAnnounce(uint8_t announceId, SleAnnounceData *data, const SleAnnounceParam *param)
{
    SLE_LOGI("StartAnnounce announceId(%hu)", announceId);
    SLE_ASSERT_AND_RETURN_RET(announceId >= 1 && announceId <= SLE_MAX_ANNOUNCE_ID_NUM, SLE_ERR_INVALID_PARAM);
    SleErrorCode ret = CheckCanOprateAnnounce();
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    SLE_ASSERT_AND_RETURN_RET(data != NULL, SLE_ERR_INVALID_PARAM);
    SLE_ASSERT_AND_RETURN_RET(g_announceState[announceId -1] != SLE_ANNOUNCE_ENABLED_STATE, SLE_ERR_EBABLE_ANNOUNCE_SUCCESS_WHEN_ANNOUNCE);
    SLE_ASSERT_AND_RETURN_RET(g_announceState[announceId -1] == SLE_ANNOUNCE_DISABLED_STATE, SLE_ERR_STATUS_WRONG);
    ret = SetAnnounceParam(announceId, param);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    ret = SetAnnounceData(announceId, data);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    g_announceState[announceId -1] = SLE_ANNOUNCE_ENABLING_STATE;
    ret = SleAnnounceHalStartAnnounce(announceId);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    osStatus_t uwRet = osSemaphoreAcquire(g_sleAnnounceSemHandle, SleAnnounceTimeOut);
    SLE_ASSERT_AND_RETURN_RET(uwRet != osErrorTimeout, SLE_ERR_TIME_OUT);
    ret = g_sleAnnounceAsyncRet;
    return ret;
}

SleErrorCode StopAnnounce(uint8_t announceId)
{
    SLE_ASSERT_AND_RETURN_RET(announceId >= 1 && announceId <= SLE_MAX_ANNOUNCE_ID_NUM, SLE_ERR_INVALID_PARAM);
    SleErrorCode ret = CheckCanOprateAnnounce();
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    SLE_ASSERT_AND_RETURN_RET(g_announceState[announceId -1] != SLE_ANNOUNCE_DISABLED_STATE, SLE_ERR_DISABLE_ANNOUNCE_SUCCESS_WHEN_NOT_ANNOUNCE);
    SLE_ASSERT_AND_RETURN_RET(g_announceState[announceId -1] == SLE_ANNOUNCE_ENABLED_STATE, SLE_ERR_STATUS_WRONG);
    g_announceState[announceId -1] = SLE_ANNOUNCE_DISABLING_STATE;
    ret = SleAnnounceHalStopAnnounce(announceId);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    osStatus_t uwRet = osSemaphoreAcquire(g_sleAnnounceSemHandle, SleAnnounceTimeOut);
    SLE_ASSERT_AND_RETURN_RET(uwRet != osErrorTimeout, SLE_ERR_TIME_OUT);
    ret = g_sleAnnounceAsyncRet;
    return ret;
}

SleErrorCode SleConvertByteToSleAnnounceConfig(uint8_t *data, SleAnnounceParam *announceConnParam)
{
    SLE_ASSERT_AND_RETURN_RET(data != NULL, SLE_ERR_INVALID_PARAM);
    SLE_ASSERT_AND_RETURN_RET(announceConnParam != NULL, SLE_ERR_INVALID_PARAM);

    uint8_t pos = 0;
    announceConnParam->handle = *(data + pos);
    pos += sizeof(uint8_t);
    announceConnParam->mode = *(data + pos);
    pos += sizeof(uint8_t);
    announceConnParam->role = *(data + pos);
    pos += sizeof(uint8_t);
    announceConnParam->level = *(data + pos);
    pos += sizeof(uint8_t);
    announceConnParam->annonceIntervalMin = COMBINE_BYTS_32(*(data + pos), *(data + pos + 1), *(data + pos + 2), *(data + pos + 3));
    pos += sizeof(uint32_t);
    announceConnParam->annonceIntervalMax = COMBINE_BYTS_32(*(data + pos), *(data + pos + 1), *(data + pos + 2), *(data + pos + 3));
    pos += sizeof(uint32_t);
    announceConnParam->channelMap = *(data + pos);
    pos += sizeof(uint8_t);
    announceConnParam->txPower = *(data + pos);
    pos += sizeof(uint8_t);
    announceConnParam->connectIntervalMin = COMBINE_BYTS_16(*(data + pos), *(data + pos + 1));
    pos += sizeof(uint16_t);
    announceConnParam->connectIntervalMax = COMBINE_BYTS_16(*(data + pos), *(data + pos + 1));
    pos += sizeof(uint16_t);
    announceConnParam->connectLatency = COMBINE_BYTS_16(*(data + pos), *(data + pos + 1));
    pos += sizeof(uint16_t);
    announceConnParam->connectTimeout = COMBINE_BYTS_16(*(data + pos), *(data + pos + 1));
    pos += sizeof(uint16_t);

    return SLE_NO_ERROR;
}

SleErrorCode GetDefaultAnnounceParamConfig(SleAnnounceParam *announceConfig)
{
    SLE_LOGD("GetAnnounceDefaultConnectConfig In");
    SLE_ASSERT_AND_RETURN_RET(announceConfig != NULL, SLE_ERR_INVALID_PARAM);

    uint16_t realLen = 0;
    uint8_t data[SLE_NV_ANNOUNCE_CONFIG_DATA_LEN] = {0};
    SleErrorCode ret = SleUapiNvRead(SLE_NV_ANNOUNCE_ID, SLE_NV_ANNOUNCE_CONFIG_DATA_LEN, &realLen, data);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);

    return SleConvertByteToSleAnnounceConfig(data, announceConfig);
}

static bool CheckIsRegistered(const SleAnnounceCallbacks *announceCallback)
{
    for(uint8_t i = 0; i < serviceCallbackNum; i++) {
        if (g_announceCallbacks[i] == announceCallback) {
            return true;
        }
    }
    return false;
}

SleErrorCode RegisterAnnounceCallbacks(SleAnnounceCallbacks *announceCallback)
{
    SLE_LOGD("RegisterAnnounceCallbacks In");
    SLE_ASSERT_AND_RETURN_RET(g_isAnnounceServiceInit == true, SLE_ERR_NOT_READY);
    SLE_ASSERT_AND_RETURN_RET(announceCallback != NULL, SLE_ERR_INVALID_PARAM);
    SLE_ASSERT_AND_RETURN_RET(CheckIsRegistered(announceCallback) == false, SLE_NO_ERROR);
    SleErrorCode ret = SLE_ERR_FAILED;
    uint8_t count = 0;
    osMutexAcquire(g_announceCallbcakMuxHandle, 0);
    for(uint8_t count = 0; count < serviceCallbackNum; count++) {
        if (g_announceCallbacks[count] == NULL) {
            g_announceCallbacks[count] = announceCallback;
            ret = SLE_NO_ERROR;
            break;
        }
    }
    osMutexRelease(g_announceCallbcakMuxHandle);
    SLE_ASSERT_AND_RETURN_RET(count < serviceCallbackNum, SLE_ERR_NO_MEM);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    return ret;
}

SleErrorCode UnregisterAnnounceCallbacks(SleAnnounceCallbacks *announceCallback)
{
    SLE_LOGD("UnregisterAnnounceCallbacks In");
    SLE_ASSERT_AND_RETURN_RET(g_isAnnounceServiceInit == true, SLE_ERR_NOT_READY);
    SLE_ASSERT_AND_RETURN_RET(announceCallback != NULL, SLE_ERR_INVALID_PARAM);
    SLE_ASSERT_AND_RETURN_RET(CheckIsRegistered(announceCallback) == true, SLE_NO_ERROR);
    SleErrorCode ret = SLE_ERR_FAILED;
    osMutexAcquire(g_announceCallbcakMuxHandle, 0);
    for(uint8_t i = 0; i < serviceCallbackNum; i++) {
        if (g_announceCallbacks[i] == announceCallback) {
            g_announceCallbacks[i] = NULL;
            ret = SLE_NO_ERROR;
            break;
        }
    }
    osMutexRelease(g_announceCallbcakMuxHandle);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    return ret;
}
